package com.xuzimian.demo.java.proxy.dynamic

import com.xuzimian.demo.java.proxy.SubjectNoInterfaces
import javassist.util.proxy.MethodHandler
import javassist.util.proxy.ProxyFactory
import javassist.util.proxy.ProxyObject
import java.lang.reflect.Method


fun main() {
    val proxyFactory = ProxyFactory()
    proxyFactory.superclass = SubjectNoInterfaces::class.java
    val proxyClass = proxyFactory.createClass()
    var javassistProxy: SubjectNoInterfaces? = null
    try {
        javassistProxy = proxyClass.newInstance() as SubjectNoInterfaces
    } catch (e: InstantiationException) {
        e.printStackTrace()
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
    }
    assert(javassistProxy != null)
    (javassistProxy as ProxyObject?)!!.handler = JavassistHandler(SubjectNoInterfaces())
    javassistProxy!!.processBusiness()
}


internal class JavassistHandler(private val target: Any) : MethodHandler {
    @Throws(Throwable::class)
    override fun invoke(self: Any, thisMethod: Method, proceed: Method?, args: Array<Any>): Any {
        doBefore()
        val result = thisMethod.invoke(target, *args)
        doAfter()
        return result
    }

    private fun doBefore() {
        println("Before ...")
    }

    private fun doAfter() {
        println("After ...")
    }

}